package com.mocai.merchant.core.service;

import com.mocai.merchant.core.domain.ColumnMapping;
import com.mocai.merchant.core.domain.Sortable;
import com.mocai.merchant.core.mapper.SortableMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * 可排序的Service
 */
@Service
public class SortableService {

    @Autowired
    SortableMapper sortableMapper;

    /**
     * 移动位置
     */
    private enum Position {
        TOP,    // 移动到第一行
        UP,     // 往上移动一行
        DOWN,   // 往下移动一行
        BOTTOM  // 移动到最后一行
    }

    /**
     * source与target进行位置交换
     *
     * @param source
     * @param target
     * @param table
     * @param idColumn
     * @param sortColumn
     * @param <T>
     */
    public <T extends Sortable> void exchange(T source, T target, String table, String idColumn, String sortColumn) {
        sortableMapper.exchange(source, target, table, idColumn, sortColumn);
    }

    public <T extends Sortable> void exchange(T source, T target) {
        ColumnMapping cm = ColumnMapping.get(source.getClass());
        exchange(source, target, cm.getTable(), cm.getId(), cm.getSort());
    }

    /**
     * 把from移动到to的位置
     *
     * @param from
     * @param to
     * @param table
     * @param idColumn
     * @param sortColumn
     * @param <T>
     */
    public <T extends Sortable> void move(T from, T to, String table, String idColumn, String sortColumn) {
        sortableMapper.move(from, to, table, idColumn, sortColumn);
    }

    public <T extends Sortable> void move(T from, T to) {
        ColumnMapping cm = ColumnMapping.get(from.getClass());
        move(from, to, cm.getTable(), cm.getId(), cm.getSort());
    }

    /**
     * 把model移动到顶部
     *
     * @param model
     * @param table
     * @param idColumn
     * @param sortColumn
     * @param <T>
     */
    public <T extends Sortable> void top(T model, String table, String idColumn, String sortColumn) {
        move(model, table, idColumn, sortColumn, Position.TOP);
    }

    public <T extends Sortable> void top(T model) {
        move(model, Position.TOP);
    }

    /**
     * 把model往上移动一行
     *
     * @param model
     * @param table
     * @param idColumn
     * @param sortColumn
     * @param <T>
     */
    public <T extends Sortable> void up(T model, String table, String idColumn, String sortColumn) {
        move(model, table, idColumn, sortColumn, Position.UP);
    }

    public <T extends Sortable> void up(T model) {
        move(model, Position.UP);
    }

    /**
     * 把model往下移动一行
     *
     * @param model
     * @param table
     * @param idColumn
     * @param sortColumn
     * @param <T>
     */
    public <T extends Sortable> void down(T model, String table, String idColumn, String sortColumn) {
        move(model, table, idColumn, sortColumn, Position.DOWN);
    }

    public <T extends Sortable> void down(T model) {
        move(model, Position.DOWN);
    }

    /**
     * 把model移动到底部
     *
     * @param model
     * @param table
     * @param idColumn
     * @param sortColumn
     * @param <T>
     */
    public <T extends Sortable> void bottom(T model, String table, String idColumn, String sortColumn) {
        move(model, table, idColumn, sortColumn, Position.BOTTOM);
    }

    public <T extends Sortable> void bottom(T model) {
        move(model, Position.BOTTOM);
    }

    private <T extends Sortable> void move(T model, Position position) {
        ColumnMapping cm = ColumnMapping.get(model.getClass());
        move(model, cm.getTable(), cm.getId(), cm.getSort(), position);
    }

    private <T extends Sortable> void move(T model, String table, String idColumn, String sortColumn, Position position) {
        Map targetRow = null;
        switch (position) {
            case TOP:
                targetRow = (Map) sortableMapper.selectFirst(table, idColumn, sortColumn);
                break;
            case UP:
                targetRow = (Map) sortableMapper.selectPrevious(model, table, idColumn, sortColumn);
                break;
            case DOWN:
                targetRow = (Map) sortableMapper.selectNext(model, table, idColumn, sortColumn);
                break;
            case BOTTOM:
                targetRow = (Map) sortableMapper.selectLast(table, idColumn, sortColumn);
                break;
        }
        // 没有找到目标行（两种可能：1.当前行在顶部，向上移动 2.当前行在底部，向下移动）
        if (null == targetRow) {
            return;
        }
        // 同一行记录
        if (targetRow.get(idColumn).equals(model.getId())) {
            return;
        }
        try {
            Sortable target = model.getClass().newInstance();
            target.setId(targetRow.get(idColumn));
            target.setSort((Integer) targetRow.get(sortColumn));
            move(model, target, table, idColumn, sortColumn);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

}
